import vehicle.Car;
import vehicle.Bus;
import vehicle.Truck;
import vehicle.Vehicle;
import user.Administrator;
import user.User;
import user.VIPUser;

import java.sql.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

public class VehicleRentalSystem {
    private static final String DB_URL = "jdbc:mysql://localhost:3306/my?serverTimezone=GMT%2B8";
    private static final String DB_USER = "root";
    private static final String DB_PASSWORD = "1234";

    public static void main(String[] args) {
        List<Vehicle> vehicleList = getVehiclesFromDB();

        Scanner scanner = new Scanner(System.in);

        // 加载数据库驱动
        try {
            Class.forName("com.mysql.cj.jdbc.Driver");
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
            return;
        }

        System.out.println("请输入用户名：");
        String username = scanner.nextLine();
        System.out.println("请输入密码：");
        String password = scanner.nextLine();

        User user;
        if (username.equals("admin") && password.equals("1234")) {
            user = new Administrator(username, password);
        } else {
            user = new VIPUser(username, password);
        }

        if (user.login(username, password)) {
            // 检查用户是否已存在，不存在则插入
            if (!isUserExists(username)) {
                insertUserIntoDB(user);
            }
            user.operate(vehicleList);
            // 将车辆信息插入到 vehicles 表
            insertVehiclesIntoDB(vehicleList);
        } else {
            System.out.println("登录失败，请重新输入。");
        }

        scanner.close();
    }

    private static boolean isUserExists(String username) {
        try (Connection connection = DriverManager.getConnection(DB_URL, DB_USER, DB_PASSWORD);
             PreparedStatement statement = connection.prepareStatement("SELECT COUNT(*) FROM users WHERE username = ?")) {
            statement.setString(1, username);
            try (ResultSet resultSet = statement.executeQuery()) {
                if (resultSet.next()) {
                    int count = resultSet.getInt(1);
                    return count > 0;
                }
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return false;
    }

    private static void insertUserIntoDB(User user) {
        String userType = user instanceof Administrator? "Administrator" : "VIPUser";
        try (Connection connection = DriverManager.getConnection(DB_URL, DB_USER, DB_PASSWORD);
             PreparedStatement statement = connection.prepareStatement("INSERT INTO users (username, password, user_type) VALUES (?,?,?)")) {
            statement.setString(1, user.username);
            statement.setString(2, user.password);
            statement.setString(3, userType);
            int rowsInserted = statement.executeUpdate();
            if (rowsInserted > 0) {
                System.out.println("用户信息插入成功。");
            } else {
                System.out.println("用户信息插入失败。");
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    private static void insertVehiclesIntoDB(List<Vehicle> vehicleList) {
        try (Connection connection = DriverManager.getConnection(DB_URL, DB_USER, DB_PASSWORD)) {
            for (Vehicle vehicle : vehicleList) {
                String vehicleType = null;
                if (vehicle instanceof Car) {
                    vehicleType = "Car";
                } else if (vehicle instanceof Truck) {
                    vehicleType = "Truck";
                } else if (vehicle instanceof Bus) {
                    vehicleType = "Bus";
                }
                try (PreparedStatement statement = connection.prepareStatement("INSERT INTO vehicles (license_plate, brand, type, is_rented, rent_days) VALUES (?,?,?,?,?)")) {
                    statement.setString(1, vehicle.getLicensePlate());
                    statement.setString(2, vehicle.getBrand());
                    statement.setString(3, vehicleType);
                    statement.setBoolean(4, vehicle.isRented());
                    statement.setInt(5, vehicle.getRentDays());
                    int rowsInserted = statement.executeUpdate();
                    if (rowsInserted > 0) {
                        System.out.println("车辆信息插入成功：" + vehicle.getLicensePlate());
                    } else {
                        System.out.println("车辆信息插入失败：" + vehicle.getLicensePlate());
                    }
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    private static List<Vehicle> getVehiclesFromDB() {
        List<Vehicle> vehicleList = new ArrayList<>();
        try (Connection connection = DriverManager.getConnection(DB_URL, DB_USER, DB_PASSWORD);
             Statement statement = connection.createStatement();
             ResultSet resultSet = statement.executeQuery("SELECT * FROM vehicles")) {
            while (resultSet.next()) {
                String licensePlate = resultSet.getString("license_plate");
                String brand = resultSet.getString("brand");
                String type = resultSet.getString("type");
                boolean isRented = resultSet.getBoolean("is_rented");
                int rentDays = resultSet.getInt("rent_days");

                Vehicle vehicle;
                switch (type) {
                    case "Car":
                        vehicle = new Car(licensePlate, brand);
                        break;
                    case "Truck":
                        vehicle = new Truck(licensePlate, brand);
                        break;
                    case "Bus":
                        vehicle = new Bus(licensePlate, brand);
                        break;
                    default:
                        continue;
                }
                vehicle.setRented(isRented);
                vehicle.setRentDays(rentDays);
                vehicleList.add(vehicle);
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return vehicleList;
    }
}